package cn.stronglink.asset.module.rfidState.service;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.socket.TextMessage;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.toolkit.IdWorker;
import cn.stronglink.asset.message.mq.consumer.entity.Reader003Udev;
import cn.stronglink.asset.message.mq.consumer.jdEntity.Light003Detail;
import cn.stronglink.asset.message.mq.consumer.jdEntity.LightSuccessData;
import cn.stronglink.asset.message.mq.topic.ReaderInfoSender;
import cn.stronglink.asset.message.websocket.MessageHandler;
import cn.stronglink.asset.model.Alarm;
import cn.stronglink.asset.model.LightData;
import cn.stronglink.asset.model.LightU;
import cn.stronglink.asset.model.RfidState;
import cn.stronglink.asset.module.alarm.mapper.AlarmMapper;
import cn.stronglink.asset.module.assetmanage.itasset.mapper.ItassetMapper;
import cn.stronglink.asset.module.assetmanage.itasset.vo.ItAssetVo;
import cn.stronglink.asset.module.lightData.mapper.LightDataMapper;
import cn.stronglink.asset.module.lightData.service.LightDataService;
import cn.stronglink.asset.module.rfidState.mapper.RfidStateMapper;
import cn.stronglink.suite.core.util.ContextUtils;

@Service
public class RfidStateJdService {
	
	@Autowired
	private RfidStateMapper rfidStateMapper;
	@Autowired
	private ItassetMapper itassetMapper;
	@Autowired
	private AlarmMapper alarmMapper;
	@Autowired
	private LightDataMapper lightMapper;
	@Autowired
	private LightDataService lightDataService;
	@Autowired
	private MessageHandler messageHandler;
	
	private static final Logger logger = LoggerFactory.getLogger(RfidStateJdService.class);
	private ReaderInfoSender topicSender = (ReaderInfoSender) ContextUtils.getBean("readerInfoSender");

	public void updateUJingDong(String rackCode,List<Reader003Udev> list) {
		rackCode=rackCode.toUpperCase();
		ItAssetVo positionVo = itassetMapper.getRoomIdByRackConverCode(rackCode);
		List<RfidState> inventoryRfidList  = new ArrayList<RfidState>(); //实际盘到的设备
		for (int i = 0; i < list.size(); i++) {
			Reader003Udev temp =list.get(i);
			String rfid=temp.getRfid().toUpperCase();
			RfidState data =rfidStateMapper.qryReaderDataByAssetLable(rfid);
			RfidState st = new RfidState();
       		if(data!=null) {
       			st.setRfidNo(rfid);
				st.setRackConverCode(rackCode);
				st.setU(temp.getU());
       			//采集信息表里有该标签但是采集的设备号不是一个就更新成当前的采集的设备号
       			if(!data.getRackConverCode().equals(rackCode)||data.getU()!=temp.getU()) {
    				rfidStateMapper.updateRfidInfo(st);
       			 }
       		}else {
   			    //采集信息表里没有该标签添加一条采集信息
       			st.setId(IdWorker.getId());
       			st.setRackConverCode(rackCode);
       			st.setRfidNo(rfid);
       			st.setU(temp.getU());
       			st.setCreateTime(new Date());
       			try{
       			    rfidStateMapper.insertRfidState(st);   
       			}catch(Exception e){
       				e.printStackTrace();
       				continue;
       			};
       		}
       		if(positionVo!=null) 
       		  inventoryRfidList.add(st);
       		  
		}
			
		if(positionVo!=null) {
			Long rackId = positionVo.getRackId(); 
			List<RfidState> exsitRfidList = itassetMapper.getServerByRackId(rackId);
			if(inventoryRfidList!=null&&exsitRfidList!=null){
				if(inventoryRfidList.size()>0){
					 HashMap<String,Object> overMap = new HashMap<String,Object>();
					 overMap.put("inventoryRfidList", inventoryRfidList);
					 overMap.put("rackCode", rackCode);
					rfidStateMapper.deleteRfidBatch(overMap);
				}
				if(inventoryRfidList.size()==0&&exsitRfidList.size()==0){
					String json ="{\"actioncode\": \"reader005\",\"awsPostdata\": "
							+ "{\"devAddrList\": [{\"devAddrCode\":\""+rackCode+"\",\"lightCommandList\": ["
							+ "{\"loopCount\": 0,\"offTime\": 20,\"onTime\": 10,\"u\": 1},"
							+ "{\"loopCount\": 0,\"offTime\": 20,\"onTime\": 10,\"u\": 2},"
							+ "{\"loopCount\": 0,\"offTime\": 20,\"onTime\": 10,\"u\": 3},"
							+ "{\"loopCount\": 0,\"offTime\": 20,\"onTime\": 10,\"u\": 4},"
							+ "{\"loopCount\": 0,\"offTime\": 20,\"onTime\": 10,\"u\": 5},"
							+ "{\"loopCount\": 0,\"offTime\": 20,\"onTime\": 10,\"u\": 6},"
							+ "{\"loopCount\": 0,\"offTime\": 20,\"onTime\": 10,\"u\": 7},"
							+ "{\"loopCount\": 0,\"offTime\": 20,\"onTime\": 10,\"u\": 8},"
							+ "{\"loopCount\": 0,\"offTime\": 20,\"onTime\": 10,\"u\": 9},"
							+ "{\"loopCount\": 0,\"offTime\": 20,\"onTime\": 10,\"u\": 10},"
							+ "{\"loopCount\": 0,\"offTime\": 20,\"onTime\": 10,\"u\": 11},"
							+ "{\"loopCount\": 0,\"offTime\": 20,\"onTime\": 10,\"u\": 12},"
							+ "{\"loopCount\": 0,\"offTime\": 20,\"onTime\": 10,\"u\": 13},"
							+ "{\"loopCount\": 0,\"offTime\": 20,\"onTime\": 10,\"u\": 14},"
							+ "{\"loopCount\": 0,\"offTime\": 20,\"onTime\": 10,\"u\": 15},"
							+ "{\"loopCount\": 0,\"offTime\": 20,\"onTime\": 10,\"u\": 16},"
							+ "{\"loopCount\": 0,\"offTime\": 20,\"onTime\": 10,\"u\": 17},"
							+ "{\"loopCount\": 0,\"offTime\": 20,\"onTime\": 10,\"u\": 18},"
							+ "{\"loopCount\": 0,\"offTime\": 20,\"onTime\": 10,\"u\": 19},"
							+ "{\"loopCount\": 0,\"offTime\": 20,\"onTime\": 10,\"u\": 20},"
							+ "{\"loopCount\": 0,\"offTime\": 20,\"onTime\": 10,\"u\": 21},"
							+ "{\"loopCount\": 0,\"offTime\": 20,\"onTime\": 10,\"u\": 22},"
							+ "{\"loopCount\": 0,\"offTime\": 20,\"onTime\": 10,\"u\": 23},"
							+ "{\"loopCount\": 0,\"offTime\": 20,\"onTime\": 10,\"u\": 24},"
							+ "{\"loopCount\": 0,\"offTime\": 20,\"onTime\": 10,\"u\": 25},"
							+ "{\"loopCount\": 0,\"offTime\": 20,\"onTime\": 10,\"u\": 26},"
							+ "{\"loopCount\": 0,\"offTime\": 20,\"onTime\": 10,\"u\": 27},"
							+ "{\"loopCount\": 0,\"offTime\": 20,\"onTime\": 10,\"u\": 28},"
							+ "{\"loopCount\": 0,\"offTime\": 20,\"onTime\": 10,\"u\": 29},"
							+ "{\"loopCount\": 0,\"offTime\": 20,\"onTime\": 10,\"u\": 30},"
							+ "{\"loopCount\": 0,\"offTime\": 20,\"onTime\": 10,\"u\": 31},"
							+ "{\"loopCount\": 0,\"offTime\": 20,\"onTime\": 10,\"u\": 32},"
							+ "{\"loopCount\": 0,\"offTime\": 20,\"onTime\": 10,\"u\": 33},"
							+ "{\"loopCount\": 0,\"offTime\": 20,\"onTime\": 10,\"u\": 34},"
							+ "{\"loopCount\": 0,\"offTime\": 20,\"onTime\": 10,\"u\": 35},"
							+ "{\"loopCount\": 0,\"offTime\": 20,\"onTime\": 10,\"u\": 36},"
							+ "{\"loopCount\": 0,\"offTime\": 20,\"onTime\": 10,\"u\": 37},"
							+ "{\"loopCount\": 0,\"offTime\": 20,\"onTime\": 10,\"u\": 38},"
							+ "{\"loopCount\": 0,\"offTime\": 20,\"onTime\": 10,\"u\": 39},"
							+ "{\"loopCount\": 0,\"offTime\": 20,\"onTime\": 10,\"u\": 41},"
							+ "{\"loopCount\": 0,\"offTime\": 20,\"onTime\": 10,\"u\": 41},"
							+ "{\"loopCount\": 0,\"offTime\": 20,\"onTime\": 10,\"u\": 42},"
							+ "{\"loopCount\": 0,\"offTime\": 20,\"onTime\": 10,\"u\": 43},"
							+ "{\"loopCount\": 0,\"offTime\": 20,\"onTime\": 10,\"u\": 44},"
							+ "{\"loopCount\": 0,\"offTime\": 20,\"onTime\": 10,\"u\": 45},"
							+ "{\"loopCount\": 0,\"offTime\": 20,\"onTime\": 10,\"u\": 46},"
							+ "{\"loopCount\": 0,\"offTime\": 20,\"onTime\": 10,\"u\": 47},"
							+ "{\"loopCount\": 0,\"offTime\": 20,\"onTime\": 10,\"u\": 48},"
							+ "{\"loopCount\": 0,\"offTime\": 20,\"onTime\": 10,\"u\": 49},"
							+ "{\"loopCount\": 0,\"offTime\": 20,\"onTime\": 10,\"u\": 50},"
							+ "{\"loopCount\": 0,\"offTime\": 20,\"onTime\": 10,\"u\": 51},"
							+ "{\"loopCount\": 0,\"offTime\": 20,\"onTime\": 10,\"u\": 52},"
							+ "{\"loopCount\": 0,\"offTime\": 20,\"onTime\": 10,\"u\": 53},"
							+ "{\"loopCount\": 0,\"offTime\": 20,\"onTime\": 10,\"u\": 54}]}]},"							
							+ "\"timeStamp\": "+System.currentTimeMillis()+"}";
					//logger.info("********全部点灭json********"+json);
					topicSender.send("DAIO", json);

				}
			}else{
				rfidStateMapper.deleteByRackCode(rackCode);
			}
//			logger.info("********盘到的设备********"+JSONObject.toJSONString(inventoryRfidList));
//			logger.info("********台账的设备********"+JSONObject.toJSONString(exsitRfidList));
			//比较盘点结果	
			compareUDiff(inventoryRfidList,exsitRfidList,positionVo,rackCode);
		}
	}

	private void compareUDiff(List<RfidState> inventoryRfidList, List<RfidState> exsitRfidList, ItAssetVo positionVo,String rackCode) {
		Collection<String> diffentReturn = new LinkedList<String>();// 不同
		Collection<String> asReturn = new LinkedList<String>();//相同
		Collection<RfidState> overData = new HashSet<RfidState>();
		Collection<RfidState> lossData = new HashSet<RfidState>();
		Collection<RfidState> differentData = new HashSet<RfidState>();
		Collection<RfidState> normalData = new HashSet<RfidState>();
		List<RfidState> max =inventoryRfidList;
		List<RfidState> min =exsitRfidList;
		if(max.size()<min.size()){
			max=exsitRfidList;
			min=inventoryRfidList;
		}
		
	     Map<String,Integer> map = new HashMap<String,Integer>(max.size());
	     for (RfidState object : max) {
	         map.put(object.getRfidNo(), 1);
	     }
	     for (RfidState object : min) {
	         if(map.get(object.getRfidNo())==null){
	        	 diffentReturn.add(object.getRfidNo());
	        	 if(max.size()==exsitRfidList.size()&&exsitRfidList.size()!=inventoryRfidList.size()){
	        		 // 如果max<min 说明 max=bb为台账，  min=aa 为盘点 .此时盘点的不在台账中 为盘盈
	        		 overData.add(object);
	        	 }else{	// 此时说明 max=aa为盘点，     min=bb 为台账    此时台账不在盘点中  为盘亏
	        		 lossData.add(object);
	        	 }
	         }else{
	             map.put(object.getRfidNo(), 2);
	         }
	     }
	     // inventoryRfidList所有
	     Map<String,RfidState> inventoryRfidListmap = new HashMap<String,RfidState>(inventoryRfidList.size());
	     for (RfidState object : inventoryRfidList) {
	    	 inventoryRfidListmap.put(object.getRfidNo(), object);
	     }
	     
	     //exsitRfidList 所有
	     Map<String,RfidState> exsitRfidListmap = new HashMap<String,RfidState>(exsitRfidList.size());
	     for (RfidState object : exsitRfidList) {
	    	 exsitRfidListmap.put(object.getRfidNo(), object);
	     }
	     
	     for (Map.Entry<String, Integer> entry : map.entrySet()) {
	         if(entry.getValue()==1){
	        	 if(max.size()==exsitRfidList.size()&&exsitRfidList.size()!=inventoryRfidList.size()){
	        		 lossData.add(exsitRfidListmap.get(entry.getKey()));
	        	 }else{
	        		 overData.add(inventoryRfidListmap.get(entry.getKey()));
	        	 }
	         }
	         if(entry.getValue()==2){
	        	 asReturn.add(entry.getKey());
	         }
	     }
	     
	     /**
	      * 最后再判断 相同的里边有没有差异 asReturn 
	      */
	     for(Iterator<String> iter = asReturn.iterator(); iter.hasNext();){
	    	 String rfid =(String) iter.next();
	    	 RfidState inventoryRfidListobj =inventoryRfidListmap.get(rfid);
	    	 RfidState exsitRfidListobj =exsitRfidListmap.get(rfid);
	    	 if(inventoryRfidListobj.getU()!=exsitRfidListobj.getU()||!inventoryRfidListobj.getRackConverCode().equals(exsitRfidListobj.getRackConverCode())){
	    		 //差异
	    		 differentData.add(exsitRfidListmap.get(rfid));
	    	 }else{
	    		 normalData.add(inventoryRfidListmap.get(rfid));
	    	 }
	     }
	     Long roomId = positionVo.getRoomId();
		 Long rackId = positionVo.getRackId();
		 List<Integer> allList =new ArrayList<>(Arrays.asList(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54));
		 Iterator<Integer> it = allList.iterator();
		 List<Light003Detail> light003List = new ArrayList<Light003Detail>();
		//插入非法下架告警
		 if(lossData!=null&&lossData.size()>0) {
			 for(RfidState s :lossData){
				 while (it.hasNext()) {	
					 int cc =it.next();
					 if(cc==s.getU()){
						 it.remove();
					 }		
				 }
			    LightData obj = lightMapper.qryByU(rackCode,s.getU());
				if(obj!=null){
					if(!obj.getHandLight()){//手动点亮就算盘点有差异也不点亮
						Light003Detail light003 = new Light003Detail();
						light003.setLoopCount(255);
						light003.setOffTime(2);
						light003.setOnTime(2);
						light003.setU(s.getU());
						light003List.add(light003);
					}					
				}else{
					this.insertLightData(rackCode,s.getU());
					Light003Detail light003 = new Light003Detail();
					light003.setLoopCount(255);
					light003.setOffTime(2);
					light003.setOnTime(2);
					light003.setU(s.getU());
					light003List.add(light003);
				}
				String desc ="RFID号:"+s.getRfidNo()+",U位在："+s.getU()+"U的设备非法下架";
				Alarm a =alarmMapper.getAlarmByRfid(s.getRfidNo(),3L);
				if(a!=null) {
					a.setCreateTime(new Date());
					a.setTypeId(3L);
					alarmMapper.updateAlarm(a);
				}else {
					//插入报警信息	
					this.insertIntoAlarm(3L,s.getRfidNo(),s.getAssetId(),roomId+"",rackId+"",desc);
				}
			 }
		 }		 
		 
		 //插入非法上架告警
		 if(overData!=null&&overData.size()>0) {
			 for(RfidState s :overData){
				 int count = itassetMapper.qryCountByRfidNo(s.getRfidNo());
		    	 if(count>0){
		    		 differentData.add(s);
		    	 }else{		  
		    		 while (it.hasNext()) {	
						 int cc =it.next();
						 if(cc==s.getU()){
							 it.remove();
						 }		
					 }
					LightData obj = lightMapper.qryByU(rackCode,s.getU());
					if(obj!=null){
						if(!obj.getHandLight()){//手动点亮就算盘点有差异也不点亮
							Light003Detail light003 = new Light003Detail();
							light003.setLoopCount(255);
							light003.setOffTime(2);
							light003.setOnTime(2);
							light003.setU(s.getU());
							light003List.add(light003);
						}					
					}else{
						this.insertLightData(rackCode,s.getU());
						Light003Detail light003 = new Light003Detail();
						light003.setLoopCount(255);
						light003.setOffTime(2);
						light003.setOnTime(2);
						light003.setU(s.getU());
						light003List.add(light003);
					}
					String desc ="RFID号:"+s.getRfidNo()+",U位在："+s.getU()+"U的设备非法上架";
					//插入报警信息	
					Alarm a =alarmMapper.getAlarmByRfid(s.getRfidNo(),2L);
					if(a!=null) {
						a.setTypeId(2L);
						a.setCreateTime(new Date());
						alarmMapper.updateAlarm(a);
					}else {
						//插入报警信息	
						this.insertIntoAlarm(2L,s.getRfidNo(),null,roomId+"",rackId+"",desc);
					}
			    }
			}
		 }		 
		 //位置差异告警
		 if(differentData!=null&&differentData.size()>0){
			 for(RfidState rs :differentData){
				 while (it.hasNext()) {	
					 int cc =it.next();
					 if(cc==rs.getU()){
						 it.remove();
					 }		
				 }
				
				String desc ="RFID号:"+rs.getRfidNo()+",台账位置实际位置异常";
				LightData obj = lightMapper.qryByU(rackCode,rs.getU());
				if(obj!=null){
					if(!obj.getHandLight()){//手动点亮就算盘点有差异也不点亮
						Light003Detail light003 = new Light003Detail();
						light003.setLoopCount(255);
						light003.setOffTime(2);
						light003.setOnTime(2);
						light003.setU(rs.getU());
						light003List.add(light003);
					}					
				}else{
					this.insertLightData(rackCode,rs.getU());
					Light003Detail light003 = new Light003Detail();
					light003.setLoopCount(255);
					light003.setOffTime(2);
					light003.setOnTime(2);
					light003.setU(rs.getU());
					light003List.add(light003);
				}
				Alarm a =alarmMapper.getAlarmByRfid(rs.getRfidNo(),1L);
				if(a!=null) {
					a.setTypeId(1L);
					a.setCreateTime(new Date());
					alarmMapper.updateAlarm(a);
				}else {
					//插入报警信息	
					this.insertIntoAlarm(1L,rs.getRfidNo(),rs.getAssetId(),roomId+"",rackId+"",desc);
				}
		   }
		 } 
		
		 //处理正常
		 if(allList!=null&&allList.size()>0) {
			 for(Integer u :allList){
				LightData obj = lightMapper.qryByU(rackCode,u);
				if(obj!=null){
					if(!obj.getHandLight()){//手动点亮就算盘点有差异也不点亮
						Light003Detail light003 = new Light003Detail();
						light003.setLoopCount(0);
						light003.setOffTime(0);
						light003.setOnTime(0);
						light003.setU(u);
						light003List.add(light003);
					}					
				}else{
					Light003Detail light003 = new Light003Detail();
					light003.setLoopCount(0);
					light003.setOffTime(0);
					light003.setOnTime(0);
					light003.setU(u);
					light003List.add(light003);
				}
			 }
	    }
		 if(light003List!=null&&light003List.size()>0) {
			String listJson=JSONObject.toJSONString(light003List);
			String json ="{\"actioncode\": \"reader005\",\"awsPostdata\": {\"devAddrList\": [{\"devAddrCode\":\""+rackCode+"\",\"lightCommandList\": "+listJson+"}]},\"timeStamp\": "+System.currentTimeMillis()+"}";
			logger.info("********盘点点亮点灭json********"+json);
			topicSender.send("DAIO", json);
		 }
	
	}
	private void insertLightData(String rackCode, Integer u) {
		LightData data = new LightData();
		data.setId(IdWorker.getId());
		data.setCreateTime(new Date());
		data.setRackConverCode(rackCode);
		data.setInventoryLight(true);
		data.setU(u);
		data.setHandLight(false);
		lightMapper.insertLightData(data);		
		
	}

	private void insertIntoAlarm(Long typeId, String rfidNo, String assetId, String roomId, String rackId,String desc) {                   
		Alarm alarm = new Alarm();
		alarm.setId(IdWorker.getId());
		alarm.setTypeId(typeId);
		alarm.setName(rfidNo);
		alarm.setLevel("重要");
		alarm.setAssetId(assetId);
		alarm.setRoomId(roomId);
		alarm.setRackId(rackId);
		alarm.setDesc(desc);
		alarm.setCreateTime(new Date());                                                                                                                               
		alarm.setStatus(1);
		alarmMapper.insertAlarm(alarm);
		
	}

	/**
	 * 接收MQ点亮的信息
	 * @param successData
	 */
	public void doSuccess(LightSuccessData data,Long timeStamp) {	
		LightU lightU = lightMapper.getLightU(timeStamp);
		if(lightU!=null) {
			String rackCode=data.getDevAddrCode().toUpperCase();
			//查找有没有手动点亮的记录且是待处理的
			if(data.getSuccess()) {
				lightMapper.deleteLightU(timeStamp);//点亮了
				if(lightU.getStatus()) {
					//更新设备状态为亮
					LightData obj = lightMapper.qryByU(rackCode,lightU.getU());
					if(obj!=null){
						logger.info("修改点亮成功了"+lightU.getU()+"机柜号"+rackCode);
						lightDataService.updateJsonDataLight(rackCode,lightU.getU(),true);
					}else{
						logger.info("新增点亮成功了"+lightU.getU());
						LightData ld = new LightData();
						ld.setId(IdWorker.getId());
						ld.setCreateTime(new Date());
						ld.setRackConverCode(rackCode);
						ld.setInventoryLight(false);
						ld.setU(lightU.getU());
						ld.setHandLight(true);
						lightMapper.insertLightData(ld);
					}
					itassetMapper.updateIsLight(lightU.getAssetId(),1);
					Map<String,Object> result = new HashMap<>();	
					result.put("timeStamp", timeStamp+"");
					result.put("status", 1);
					logger.info(JSONObject.toJSONString(result)+"点亮成功了");
					messageHandler.sendMessageToAllUsers(new TextMessage(JSONObject.toJSONString(result)));
				}else {
					lightDataService.updateJsonDataLight(rackCode,lightU.getU(),false);
					itassetMapper.updateIsLight(lightU.getAssetId(),0);
					Map<String,Object> result = new HashMap<>();	
					result.put("timeStamp", timeStamp+"");
					result.put("status", 2);
					logger.info(JSONObject.toJSONString(result)+"点灭成功了");
					messageHandler.sendMessageToAllUsers(new TextMessage(JSONObject.toJSONString(result)));
				}
				
			}else {
				//取出该机柜中点亮失败的标签再次点亮
				if(lightU.getCount()<5){
					logger.info(data.getDevAddrCode()+"点亮失败了再次点亮");
					if(lightU.getDataJson()!=null&&!"".equals(lightU.getDataJson())) {
						topicSender.send("DAIO", lightU.getDataJson());
						lightMapper.updateLightCount(timeStamp);
					}
				}else{
					lightMapper.deleteLightU(timeStamp);
					Map<String,Object> result = new HashMap<>();	
					result.put("timeStamp", timeStamp+"");
					result.put("status", 0);
					logger.info(JSONObject.toJSONString(result)+"点亮点灭失败");
					messageHandler.sendMessageToAllUsers(new TextMessage(JSONObject.toJSONString(result)));
				}
				
			}
		}
	}

	
}
